module AbsC where

import qualified Data.Map as Map

type DefVars = [Id]
type PCOffset = Int

data FunIdent = Fun Id Int
    deriving (Eq,Ord,Show)
   
data FunInfo = FI [Parameter] Type Int
   | FErr String
  deriving (Eq,Ord,Show)
   
data VarInfo = VI Type PCOffset (Maybe Modality)
   | VErr String
  deriving (Eq,Ord,Show)

newtype Id = Id String deriving (Eq,Ord,Show)

data Program =
   Prog [Decl] String
  deriving (Eq,Ord,Show)

data Decl =
   DFun Type FunIdent [Parameter] Stmt 
 | DVar Type Id (Maybe (InitVar)) PCOffset
  deriving (Eq,Ord,Show)

data Parameter =
   Param Modality Type Id
  deriving (Eq,Ord,Show)

data InitVar =
   EVar Type
 | SIVar (RExpr,Type)
 | CIVar [InitVar] Type
  deriving (Eq,Ord,Show)

data RExpr =
   InfixOp InfixOp (RExpr,Type) (RExpr,Type)
 | UnaryOp UnaryOp (RExpr,Type)
 | FCall FunIdent [(RExpr,Type)]
 | Const Const
 | LExpr (LExpr,Type)
 | Ref (LExpr,Type)
 | PrePostIncDecr PrePostIncDecr (LExpr,Type)
 | Coertion Type Type RExpr
  deriving (Eq,Ord,Show)
  
data InfixOp = ArithOp ArithOp | RelOp RelOp | BoolOp BoolOp
  deriving (Eq,Ord,Show)
  
data ArithOp = Add | Sub | Mul | Div | Mod | Pow
  deriving (Eq,Ord,Show)
 
data BoolOp = Or | Xor | And
  deriving (Eq,Ord,Show)
  
data RelOp = Eq | NEq | Lt | LtE | Gt | GtE
  deriving (Eq,Ord,Show)

data UnaryOp = Not | Neg
  deriving (Eq,Ord,Show)
  
data Const = Bool Bool | Char Char | Float Double | Int Int | String String
  deriving (Eq,Ord,Show)

data LExpr =
   Deref (RExpr,Type)
 | ArrayEl (LExpr,Type) (RExpr,Type)
 | SId Id String
  deriving (Eq,Ord,Show)

data PrePostIncDecr = PostDecr | PostInc | PreDecr | PreInc
  deriving (Eq,Ord,Show)
  
data AssignmentOp = Assign | AssgnArith ArithOp | AssgnBool BoolOp
  deriving (Eq,Ord,Show)

data Stmt =
   Block [Decl] [Stmt]
 | Jmp JumpStmt
 | Iter IterStmt
 | Sel SelectionStmt
 | RExprStmt (RExpr,Type)
 | Assgn AssignmentOp (LExpr,Type) (RExpr,Type)
  deriving (Eq,Ord,Show)

data JumpStmt =
   Break String
 | Continue String
 | RetExpVoid Type
 | RetExp (RExpr,Type)
  deriving (Eq,Ord,Show)

data SelectionStmt =
   IfNoElse (RExpr,Type) Stmt
 | IfElse (RExpr,Type) Stmt Stmt
  deriving (Eq,Ord,Show)

data IterStmt =
   While (RExpr,Type) Stmt
 | DoWhile Stmt (RExpr,Type)
  deriving (Eq,Ord,Show)

data Modality =
   Modality_val
 | Modality_valres
  deriving (Eq,Ord,Show)

data Type =
   BType BasicType
 | PType Type
 | Array Int Type
 | TErr String
  deriving (Eq,Ord,Show)
  
data BasicType =
   BTBool
 | BTChar
 | BTInt
 | BTFloat
 | BTVoid
  deriving (Eq,Ord,Show)

typeWidth :: Type -> Int
typeWidth (BType b) = bTypeWidth b
typeWidth (PType _) = 1
typeWidth (Array i t) = i * tw
   where
      tw = typeWidth t
typeWidth _ = 0
      
bTypeWidth :: BasicType -> Int
bTypeWidth b = case b of
   BTInt -> 4
   BTFloat -> 8
   BTVoid -> 0
   _ -> 1

data Address = Var Id
 | Temp Int 
 | Constant Const 
   deriving (Eq,Ord,Show)
data Label = L Int
	| F FunIdent
	| N
	| Fall
    deriving (Eq,Ord,Show)
type PC = Int
type Code = Map.Map PC LabInst
type LabInst = ((Maybe Label),Instruction)
data Instruction = AssBin InfixOp Address Address Address
	|AssUn UnaryOp Address Address
	|Copy Address Address
	|Goto Label
	|If Address Label
	|IfFalse Address Label
	|IfRel RelOp Address Address Label
	|Call Address Label
	|RetVoid
	|Ret Address
	|Par Address --parameter
	|AEl Address Address Address
	|AssAEl Address Address Address
	|AssRef Address Address
	|ArrRef Address Address Address
	|AssDeref Address Address
	|AssVtoP Address Address
	|NoOp
   |Cast Type Address Address
      deriving (Eq,Ord,Show)
